package com.xiaolin.generic;

import java.time.Period;

/**
 * @ClassName GenericMethodTest
 * @Description 泛型方法，方法所属的类并没有指定泛型
 * @Detail
 *          使用泛型的两个意义：
 *              1、适用于多种数据类型执行相同的代码（代码复用）
 *              2、泛型中的类型在使用时指定，不需要强制类型转换（类型安全，编译器会检查类型）
 * @Author MyPC
 * @Date 2020/11/30
 * @Version 1.0
 */
public class GenericMethodTest {


    public static void main(String[] args) {
        // 第一种调用方式，不知道类型，由编译器帮我们自动识别
        Integer f1 = first(11, 12);
        System.out.println(f1);
        // 第二种调用方式，指定类型
        String f2 = GenericMethodTest.<String>first("hello", "hi");
        System.out.println(f2);
        out("小林");
        People p1 = GenericMethodTest.<People>get("小红");
        System.out.println(p1.getName());
    }

    /**
     * 泛型方法 1，有返回值
     * @param d1  参数名
     * @param d2  参数名
     * @param <T>  返回值类型
     * @return  返回值类型也必须是T
     */
    public static <T> T first(T d1,T d2){
        System.out.println(d1);
        return d1;
    }

    /**
     *  泛型方法 2，无返回值
     * @param t  参数名
     * @param <T>  参数类型
     */
    public static <T> void out(T t){
        System.out.println(t);
    }

    /**
     *  泛型方法 3，限定泛型的范围
     * @param name
     * @param <T>
     * @return 返回值一定是People类型的对象
     */
    public static <T extends People> T get(String name){
        People people = new People();
        people.setName(name);
        return (T)people;
    }

}

class People{
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
